﻿namespace SilvesterWeb
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Linq;
    using System.Net;
    using System.Text;
    using System.Web.Services;
    using System.Xml;
    using System.Xml.Linq;
    using SilvesterWeb.BusinessObjects;

    /// <summary>
    /// Twitter proxy
    /// </summary>    
    [WebService( Namespace = "http://tempuri.org/" )]
    [WebServiceBinding( ConformsTo = WsiProfiles.BasicProfile1_1 )]
    [ToolboxItem( false )]
    [System.Web.Script.Services.ScriptService]
    public class TwitterWebService : System.Web.Services.WebService
    {
        private const string UserTimelineUri = "http://twitter.com/statuses/user_timeline/{0}.xml";
        private const string StatusElementName = "status";
        private const string CreatedAtElementName = "created_at";
        private const string TextElementName = "text";
        private const string ProfileImageUrlElementName = "profile_image_url";
        private const string ScreenNameElementName = "screen_name";
        private const string UserElementName = "user";
        private const string UserUrlElementName = "url";

        [WebMethod]
        public List<Status> GetUserTimeline( string twitterUser, string userName, string password )
        {
            if ( string.IsNullOrEmpty( twitterUser ) )
            {
                throw new ArgumentNullException( "twitterUser", "twitterUser parameter is mandatory" );
            }

            Uri timelineUri = new Uri( string.Format( UserTimelineUri, twitterUser ) );
            WebRequest rq = HttpWebRequest.Create( timelineUri );

            if ( !string.IsNullOrEmpty( userName ) && !string.IsNullOrEmpty( password ) )
            {
                string up = userName + ":" + password;
                CredentialCache cache = new CredentialCache();
                cache.Add( timelineUri, "Basic", new NetworkCredential( userName, password ) );
                rq.Credentials = cache;
                rq.Headers.Add( "Authorization", "Basic " + Convert.ToBase64String( new ASCIIEncoding().GetBytes( up ) ) );
            }

            HttpWebResponse res = rq.GetResponse() as HttpWebResponse;

            // rate limit exceeded
            if ( res.StatusCode == HttpStatusCode.BadRequest )
            {
                throw new ApplicationException( "Rate limit exceeded" );
            }

            XDocument xmlStatusData = XDocument.Load( XmlReader.Create( res.GetResponseStream() ) );
            List<Status> data = ( from status in xmlStatusData.Descendants( StatusElementName )
                                  select new Status
                                  {
                                      CreatedAt = status.Element( CreatedAtElementName ).Value.Trim(),
                                      Text = status.Element( TextElementName ).Value.Trim(),
                                      User = new User()
                                      {
                                          ProfileImageUrl = status.Element( UserElementName ).Element( ProfileImageUrlElementName ).Value.Trim(),
                                          ScreenName = status.Element( UserElementName ).Element( ScreenNameElementName ).Value.Trim(),
                                          Url = status.Element( UserElementName ).Element( UserUrlElementName ).Value.Trim()
                                      }
                                  } ).ToList();

            return data;
        }
    }
}
